<?php
/**
 * Created by PhpStorm.
 * User: xiangfeng
 * Date: 2022/4/8
 * Time: 10:36 PM
 */

namespace app\api\controller;


use app\api\http\exceptions\ApiErr;
use app\api\http\exceptions\ApiExceptions;
use app\api\service\UserService;
use app\api\service\UserTokenService;
use app\api\validate\UserValidate;
use WeMini\Crypt;
use WeMini\Message;

/**
 * 用户登录获取Token
 * Class Login
 * @package app\api\controller
 */
class Login extends BaseApi
{

    /**
     * 3、获取手机号码
     * @return \think\response\Json
     * @throws ApiExceptions
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserPhone()
    {
        $redis = $this->redis;
        $param = $this->app->request->param();
        if (empty($param['js_phone_code'])) {
            throw new ApiExceptions(ApiErr::ERROR_PARAMS);
        }
        $redis->lPush('phoneInfo', json_encode($param));
        $js_code = $param['js_phone_code'];
        $crypt = Crypt::instance(['appid' => APP_KEY, 'appsecret' => APP_SECRET]);
        $result = $crypt->phoneInfo($js_code);
        $redis->lPush('phoneInfo', json_encode($result));
        if ($result['errcode'] != 0) {
            throw new ApiExceptions(ApiErr::USER_AUTH_PHONE_FAILED);
        }
        $phone_info = $result['phone_info'];
        $phone = isset($phone_info['phoneNumber']) ? $phone_info['phoneNumber'] : '';
        if (empty($phone)) {
            throw new ApiExceptions(ApiErr::USER_AUTH_PHONE_FAILED);
        }
        $db = $this->app->db;
        $filed = 'college_name,college_dep_name,uname,phone,birthday,join_year,join_type,working_unit,email,image_list,introduce';
        $user = $db->name('qt_user')->field($filed)->where(['phone' => $phone, 'is_reg' => 0, 'certification_status' => 0])->find();
        $data = [
            'phone' => $phone,
            'college_name' => !empty($user['college_name']) ? $user['college_name'] : '',
            'college_dep_name' => !empty($user['college_dep_name']) ? $user['college_dep_name'] : '',
            'uname' => !empty($user['uname']) ? $user['uname'] : '',
            'birthday' => !empty($user['birthday']) ? $user['birthday'] : '',
            'join_year' => !empty($user['join_year']) ? $user['join_year'] : '',
            'join_type' => !empty($user['join_type']) ? $user['join_type'] : '',
            'working_unit' => !empty($user['working_unit']) ? $user['working_unit'] : '',
            'email' => !empty($user['email']) ? $user['email'] : '',
            'image_list' => !empty($user['image_list']) ? json_decode($user['image_list'], true) : [],
            'introduce' => !empty($user['introduce']) ? $user['introduce'] : '',

        ];
        return $this->jsonSuccessResponse($data);
    }

    /**
     * 1、小程序授权登录
     * @return \think\response\Json
     * @throws ApiExceptions
     * @throws \WeChat\Exceptions\InvalidDecryptException
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function authLogin()
    {
        $redis = $this->redis;
        $param = $this->app->request->param();
        if (empty($param['js_code']) || empty($param['iv']) || empty($param['encryptedData'])) {
            throw new ApiExceptions(ApiErr::ERROR_PARAMS);
        }
        $js_code = $param['js_code'];
        $iv = $param['iv'];
        $encryptedData = $param['encryptedData'];
        $crypt = Crypt::instance(['appid' => APP_KEY, 'appsecret' => APP_SECRET]);
        $wxInfo = $crypt->userInfo($js_code, $iv, $encryptedData);
        if (empty($wxInfo['openid'])) {
            throw new ApiExceptions(ApiErr::USER_AUTH_LOGIN_ERROR);
        }
        $openid = $wxInfo['openid'];
        $wx_data = [
            'openid' => $openid,
            'nickname' => isset($wxInfo['nickName']) ? $wxInfo['nickName'] : '',
            'avatar' => isset($wxInfo['avatarUrl']) ? $wxInfo['avatarUrl'] : '',
        ];
        $redis->lPush('userInfo', json_encode($wxInfo));
        $db = $this->app->db;
        $third_binding = $db->name('qt_third_binding')->where(['openid' => $openid])->find();
        $third_user_id = !empty($third_binding) ? (int)$third_binding['user_id'] : 0;
        if ($third_user_id <= 0) {
            $apiErrConst = ApiErr::GET_USER_INFORMATION_FAILED;//此code 需拿openid 授权获取手机号注册
            // exit($this->jsonErrResponse($apiErrConst[0], $apiErrConst[1], $wx_data));
            return $this->jsonResponse($apiErrConst[0], $apiErrConst[1], $wx_data, 200);
        }
        $user = $db->name('qt_user')->field('id,status')->where(['id' => $third_user_id])->find();
        $status = !empty($user) ? (int)$user['status'] : 1;
        if ($status > 0) throw new ApiExceptions(ApiErr::USER_ABNORMAL_ACCOUNT);
        $token = UserTokenService::token($third_user_id);
        return $this->jsonSuccessResponse($token);
    }

    /**
     * 2、授权注册登录
     * @return \think\response\Json
     * @throws ApiExceptions
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function authRegister()
    {
        $param = $this->app->request->param();
        if (empty($param['openid'])) {
            throw new ApiExceptions(ApiErr::ERROR_PARAMS);
        }
        try {
            validate(UserValidate::class)->scene('add')->check($param);
        } catch (\Exception $exception) {
            $apiErrConst = ApiErr::UPDATE_DB_FAILED;
            throw new ApiExceptions([$apiErrConst[0], $exception->getMessage()]);
        }
        $phone = $param['phone'];
        $db = $this->app->db;
        $add_param = [
            'openid' => $param['openid'],
            'phone' => $phone,
            'nickname' => $param['uname'],
            'avatar' => isset($param['avatar']) ? $param['avatar'] : '',
            'create_time' => time(),
            'uname' => $param['uname'],
            'birthday' => $param['birthday'],
            'college_name' => $param['college_name'],
            'college_dep_name' => $param['college_dep_name'],
            'join_year' => $param['join_year'],
            'join_type' => $param['join_type'],
            'working_unit' => $param['working_unit'],
            'email' => $param['email'],
            'introduce' => $param['introduce'],
            'image_list' => !empty($param['image_list']) ? json_encode($param['image_list']) : [],
            'certification_status' => 0,
            'is_reg' => 1,
        ];
        /********************************************/
        $add_third_info = [
            'openid' => $param['openid'],
            'phone' => $phone,
            'nickname' => isset($param['nickname']) ? $param['nickname'] : '',
            'avatar' => isset($param['avatar']) ? $param['avatar'] : '',
            'create_time' => time(),
        ];
        $third_binding = $db->name('qt_third_binding')->where(['openid' => $param['openid']])->find();
        $third_user_id = !empty($third_binding) ? $third_binding['id'] : 0;
        if ($third_user_id > 0) {
            /**********************查询存在绑定记录直接返回Token***************************/
            return $this->jsonSuccessResponse(UserTokenService::token($third_user_id));
        }
        /**********************查询是否存在记录直接返回Token***************************/
        $user = $db->name('qt_user')->field('id,status,certification_status,is_reg')->where(['phone' => $phone])->find();
        if (!empty($user)) {
            if ($user['status'] != 0) throw new ApiExceptions(ApiErr::USER_ABNORMAL_ACCOUNT);
            if ($user['is_reg'] == 0) {
                $update_param = [
                    'is_reg' => 1,
                    'openid' => $param['openid'],
                    'phone' => $phone,
                    'nickname' => $param['uname'],
                    'avatar' => isset($param['avatar']) ? $param['avatar'] : '',
                    'update_time' => time(),
                    'uname' => $param['uname'],
                    'birthday' => $param['birthday'],
                    'college_name' => $param['college_name'],
                    'college_dep_name' => $param['college_dep_name'],
                    'join_year' => $param['join_year'],
                    'join_type' => $param['join_type'],
                    'working_unit' => $param['working_unit'],
                    'email' => $param['email'],
                    'introduce' => $param['introduce'],
                    'image_list' => !empty($param['image_list']) ? json_encode($param['image_list']) : [],
                ];
                $db->name('qt_user')->where(['id' => $user['id']])->update($update_param);
                $db->name('qt_third_binding')->insert(array_merge($add_third_info, [
                    'user_id' => $user['id']
                ]));
            }
            return $this->jsonSuccessResponse(UserTokenService::token($user['id']));
        }
        /**********************查询是否不存在记录***************************/
        $user_id = $db->name('qt_user')->insertGetId($add_param);
        if ($user_id <= 0) {
            throw new ApiExceptions(ApiErr::INSERT_DB_FAILED);
        }
        $row = $db->name('qt_third_binding')->insert(array_merge($add_third_info, [
            'user_id' => $user_id
        ]));
        if (!$row) {
            throw new ApiExceptions(ApiErr::INSERT_DB_FAILED);
        }
        return $this->jsonSuccessResponse(UserTokenService::token($user_id));
    }

    /**
     * 1.1、帐号登录(废弃)
     * @return \think\response\Json
     * @throws ApiExceptions
     */
    public function doLogin()
    {
        $param = $this->app->request->param();
        if (empty($param['uname'])) {
            throw new ApiExceptions(ApiErr::ERROR_PARAMS);
        }
        $uid = UserService::getUidByPhone($param['uname']);
        $token = UserTokenService::token($uid);
        return $this->jsonSuccessResponse($token);
    }

    /**
     * 退出登录
     * @return \think\response\Json
     * @throws ApiExceptions
     */
    public function loginOut()
    {
        $token = $this->request->header('token');
        $login_info = $this->login_user;
        $user_id = isset($login_info['user_id']) ? (int)$login_info['user_id'] : 0;
        $role_id = isset($login_info['role_id']) ? (int)$login_info['role_id'] : 0;
        $key = USER_TOKEN_PREFIX . $user_id . '' . $role_id;
        $user_token_key = USER_TOKEN_PREFIX . md5($token);
        $res = false;
        $resToken = false;
        if ($this->redis->exists($key)) {
            $res = $this->redis->del($key);
        }
        if ($this->redis->exists($user_token_key)) {
            $resToken = $this->redis->del($user_token_key);
        }
        if ($resToken && $res) {
            return $this->jsonSuccessResponse();
        } else {
            throw new ApiExceptions(ApiErr::UPDATE_DB_FAILED);
        }
    }

}